package integrated

import (
	"encoding/json"
	"fmt"
	"github.com/pkg/errors"
	"reflect"
	"talent.com/agency_im/common/msg"
	"talent.com/agency_im/common/pay"
	"talent.com/agency_im/conf"
	"talent.com/agency_im/modules/core"
	"talent.com/server/durotar.git/log"
	"time"
)

type AgencyPayInterceptor struct{}

func (m *AgencyPayInterceptor) PreHandle(*msg.Message) (bool, error) {
	return true, nil
}

func (m *AgencyPayInterceptor) PostHandle(message *msg.Message) error {
	log.Debug("post handle message on pay interceptor, message: %+v", message)
	if message.MsgType != int8(msg.MSG_TYPE_CUSTOM) {
		return nil
	}
	var (
		payMsg baseMessageFrame
		err    error
	)
	if err = json.Unmarshal([]byte(message.Info), &payMsg); err != nil {
		return err
	}

	switch payMsg.Type {
	case MsgTypeSelectPayType:
		data := selectPayTypeMsg{}
		if err := decodeMsgData(payMsg.Data, &data); err != nil {
			return err
		}
		if err = handleSelectPayType(message, &data); err != nil {
			return err
		}
	case MsgTypeSelectPayAmount:
		data := selectPayAmountMsg{}
		if err := decodeMsgData(payMsg.Data, &data); err != nil {
			return err
		}
		if err = handleSelectPayAmount(message, &data); err != nil {
			return err
		}
	case MsgTypeGetPayTypeDetail, MsgGetPayOrderDetail, MsgTypeGetPayTypeAmountLevels:
		return nil
	default:
		return errors.Errorf("custom pay message type not support: %v", payMsg.Type)
	}
	return nil
}

// 处理消息：用户选择充值分类
// 根据用户选择的充值分类查询所有对应可用的收款方式列表，如果当前收款列表中有『自助下发』收款，则自动
// 发送给用户该收款方式，如果有多个收款方式支持自助下发，则随机选择一个。如果没有任何自助下发收款，则忽略该消息，
// 等代理人员手动处理
func handleSelectPayType(message *msg.Message, req *selectPayTypeMsg) error {
	var (
		err     error
		receipt *pay.ReceiptAddress
	)

	if receipt, err = pay.GetAgencyReceiptAddress(message.SourceID, message.TargetID, req.PayType, false); err != nil {
		errorInfo := "当前系统繁忙，请稍候重试"
		switch err.Error() {
		case "3301":
			time.Sleep(time.Second * 2)
			err = core.SendMessage(&msg.Message{
				TopicType: message.TopicType,
				SourceID:  message.TargetID,
				TargetID:  message.SourceID,
				MsgType:   int8(msg.MSG_TYPE_TEXT),
				SendSelf:  false,
				Info:      "好的，马上为您准备收款账号，请您耐心等待一下。",
			})
			return err
		case "3302":
			errorInfo = "该支付方式当前不可用，请选择其他支付方式"
		case "3303", "3304":
			errorInfo = "专员已被禁用，若有疑问请联系在线客服"
		default:
			return err
		}
		core.SendErrorMsg(message.SourceID, errorInfo)
		return nil
	}

	if receipt.ID == 0 {
		return errors.New("assert fail")
	}

	time.Sleep(time.Millisecond * 600)

	if err = handleReceiptAddress(receipt, message.TargetID, message.SourceID); err != nil {
		return err
	}

	return nil
}

func handleReceiptAddress(receipt *pay.ReceiptAddress, agencyID uint64, playerID uint64) (err error) {
	if receipt.AutoArrival {
		// 自助上分订单，发送询问下单额度消息
		if err = sendPayMsg(agencyID, playerID, getPayTypeAmountLevelsMsg{
			ReceiptAddressID:  receipt.ID,
			PayType:           receipt.PayType,
			Quotas:            []int64{10000, 50000, 200000, 500000, 1000000},
			AmountAllowCustom: true,
			AmountMin:         5000,
			AmountMax:         5000000,
			AmountUnit:        100,
		}); err != nil {
			return err
		}
	} else {
		// 发送收款账户消息
		if err = sendPayMsg(agencyID, playerID, getPayTypeDetailMsg{
			ReceiptAddressID: receipt.ID,
			PayType:          receipt.PayType,
			PayUrl:           conf.ServerConfig().Pay.PayFrontHost + fmt.Sprintf("?pay_method=%v&receipt_id=%v", receipt.PayMethod, receipt.ID),
		}); err != nil {
			return err
		}

		err = core.SendMessage(&msg.Message{
			TopicType: int8(msg.TOPIC_TYPE_PRIVATE),
			SourceID:  agencyID,
			TargetID:  playerID,
			MsgType:   int8(msg.MSG_TYPE_TEXT),
			SendSelf:  false,
			Info:      "请点击上方小卡片进行充值，充好了麻烦提供支付凭证截图给我，我给您加币。",
		})
		if err != nil {
			return err
		}
	}
	return nil
}

// 处理用户选择或者输入特定充值金额消息
// 如果是手动上分方式，则发送收款方式给用户，如果是自动上分方式，则创建订单并发送订单给用户
func handleSelectPayAmount(message *msg.Message, req *selectPayAmountMsg) error {
	var (
		err error
	)

	var order *pay.RechargeOrder
	if order, err = pay.CreatePayOrder(message.SourceID, message.TargetID, req.Amount, req.ReceiptAddressID, req.PayType); err != nil {
		return err
	} else {
		if err = sendPayMsg(message.TargetID, message.SourceID, getPayOrderDetailMsg{
			OrderID:          order.ID,
			ReceiptAddressID: order.ReceiptAddressID,
			PayType:          order.PayType,
			PayUrl:           conf.ServerConfig().Pay.PayFrontHost + fmt.Sprintf("?order_id=%v", order.ID),
		}); err != nil {
			return err
		}

		err = core.SendMessage(&msg.Message{
			TopicType: message.TopicType,
			SourceID:  message.TargetID,
			TargetID:  message.SourceID,
			MsgType:   int8(msg.MSG_TYPE_TEXT),
			SendSelf:  false,
			Info:      fmt.Sprintf("本次充值您需要转账【%.2f】元，请注意付款时转账金额必须保持一致才能充值到账，金额不一致将不会到账。", float32(float32(order.RealAmount)/100.00)),
		})
		if err != nil {
			return err
		}
	}

	return nil
}

func sendPayMsg(agencyID uint64, playerID uint64, data interface{}) error {
	msgType, ok := msgTypeMap[reflect.TypeOf(data)]
	if !ok {
		return errors.Errorf("not support pay msg type : %T", data)
	}

	dataBytes, err := json.Marshal(data)
	if err != nil {
		return nil
	}

	bytes, err := json.Marshal(baseMessageFrame{
		Type: msgType,
		Data: dataBytes,
	})
	if err != nil {
		return err
	}
	err = core.SendMessage(&msg.Message{
		TopicType: int8(msg.TOPIC_TYPE_PRIVATE),
		SourceID:  agencyID,
		TargetID:  playerID,
		MsgType:   int8(msg.MSG_TYPE_CUSTOM),
		SendSelf:  false,
		Info:      string(bytes),
	})
	if err != nil {
		return err
	}
	return nil
}
